#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>
#include <boost/thread/thread.hpp>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/asio/thread_pool.hpp>
#include <boost/lexical_cast.hpp>

using namespace std;
using namespace cv;
          		         
#define PIC_FOLDER_PATH "I:/pic/"         

void Task(Mat p_img) {
	string windows_name = boost::lexical_cast<std::string>(boost::this_thread::get_id());
	namedWindow(windows_name, WINDOW_AUTOSIZE);
	imshow(windows_name, p_img);

	waitKey(1);
	p_img.release();
	destroyAllWindows();
	Sleep(1);
}

void ShowImg(Mat p_img, int index) {
	char windows_name[32];
	sprintf_s(windows_name, "%d", index);
	namedWindow(windows_name, WINDOW_AUTOSIZE);
	imshow(windows_name, p_img);

	waitKey(1);
	p_img.release();
	destroyAllWindows();
	Sleep(1);
}

void ExecuteWithThreadpool() {
	boost::asio::thread_pool tp(16);
	char file_name[32];
	Mat p_img;
	vector<Mat> v;
	for (int index = 1; index < 11; index++) {
		sprintf_s(file_name, "%s%d.jfif", PIC_FOLDER_PATH, index);
		p_img = imread(file_name, 1);
		v.push_back(p_img);
	}

	vector<Mat>::iterator it;
	int index = 0;
	for (it = v.begin(); it != v.end(); it++) {
		// Submit a function to the pool.
		boost::asio::post(tp, std::bind(Task,*it));
		cout << "===========" << index++ << "===========" << endl;
	}
	// Wait for all tasks in the pool to complete.
	tp.join();
	cout << "end!" << endl;
}

void ExecuteWithNotThread() {
	char file_name[32];

	Mat p_img;
	vector<Mat> v;
	for (int index = 1; index < 11; index++) {
		sprintf_s(file_name, "I:/pic/%d.jfif", index);
		p_img = imread(file_name, 1);
		v.push_back(p_img);
	}

	vector<Mat>::iterator it;
	int index = 0;
	for (it = v.begin(); it != v.end(); it++) {
		ShowImg(*it, index);
		cout << "===========" << index++ << "===========" << endl;
	}

	cout << "end!" << endl;
}

int main() {
	double start, end;
	start = clock();
	ExecuteWithNotThread();
	end = clock();
	cout << "ExecuteWithNotThread: " << (end - start) / 1000 << endl;

	start = clock();
	ExecuteWithThreadpool();
	end = clock();
	cout << "ExecuteWithThreadpool: " << (end - start) / 1000 << endl;
	return 0;
}